import pygame
import math
import time
from typing import Dict, List, TYPE_CHECKING, Tuple, Optional
import re

from models import Position, Vehicle, Direction, TrafficLightStatus
from user_system import UserSystem  # 导入用户系统

if TYPE_CHECKING:
    from main import TrafficSystem

class Colors:
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    YELLOW = (255, 255, 0)
    GRAY = (128, 128, 128)
    BLUE = (0, 0, 255)
    LIGHT_BLUE = (100, 150, 255)
    DARK_BLUE = (0, 50, 150)

class TrafficVisualization:
    def __init__(self, width: int = 800, height: int = 700):
        pygame.init()
        self.width = width
        self.height = height
        self.screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("路径规划系统")
        
        # 初始化用户系统
        self.user_system = UserSystem()
        
        # 启用文本输入
        pygame.key.set_repeat(500, 30)
        
        self.cell_size = 100  # 网格大小
        self.intersection_radius = 10
        self.vehicle_radius = 5
        
        # 使用系统中文字体
        try:
            # 尝试使用系统默认中文字体
            self.font = pygame.font.SysFont("microsoftyahei", 36)  # 微软雅黑
            self.small_font = pygame.font.SysFont("microsoftyahei", 24)
            self.tiny_font = pygame.font.SysFont("microsoftyahei", 16)  # 添加小号字体
        except:
            try:
                # 备选方案：使用其他常见中文字体
                self.font = pygame.font.SysFont("simsun", 36)  # 宋体
                self.small_font = pygame.font.SysFont("simsun", 24)
                self.tiny_font = pygame.font.SysFont("simsun", 16)
            except:
                print("警告：未找到中文字体，使用默认字体")
                self.font = pygame.font.Font(None, 36)
                self.small_font = pygame.font.Font(None, 24)
                self.tiny_font = pygame.font.Font(None, 16)
        
        # 输入状态
        self.input_state = "start"  # "start" 或 "dest"
        self.selected_pos = None
        self.start_pos = None
        self.dest_pos = None
        
        # 添加到达目的地提示相关属性
        self.show_arrival_message = False
        self.message_start_time = 0
        self.message_duration = 3.0  # 显示3秒
        
    def coordinate_transform(self, pos: Position) -> tuple:
        """将系统坐标转换为屏幕坐标"""
        screen_x = pos.x * self.cell_size + self.width // 4
        screen_y = pos.y * self.cell_size + self.height // 4
        return (screen_x, screen_y)
    
    def draw_road(self, start: Position, end: Position, density: float):
        """绘制道路，颜色根据密度变化"""
        start_pos = self.coordinate_transform(start)
        end_pos = self.coordinate_transform(end)
        
        # 根据密度计算颜色
        color_value = int(255 * (1 - density))
        road_color = (color_value, color_value, color_value)
        
        # 绘制道路主体
        pygame.draw.line(self.screen, road_color, start_pos, end_pos, 8)
        
        # 绘制道路方向箭头
        self.draw_arrow(start_pos, end_pos, Colors.GRAY)
        
    def draw_arrow(self, start: tuple, end: tuple, color: tuple):
        """绘制箭头表示道路方向"""
        arrow_size = 10
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        angle = math.atan2(dy, dx)
        
        # 计算箭头位置（道路中点）
        mid_x = (start[0] + end[0]) // 2
        mid_y = (start[1] + end[1]) // 2
        
        # 绘制箭头
        points = [
            (mid_x - arrow_size * math.cos(angle - math.pi/6),
             mid_y - arrow_size * math.sin(angle - math.pi/6)),
            (mid_x, mid_y),
            (mid_x - arrow_size * math.cos(angle + math.pi/6),
             mid_y - arrow_size * math.sin(angle + math.pi/6))
        ]
        pygame.draw.lines(self.screen, color, False, points, 2)
        
    def draw_intersection(self, pos: Position, traffic_light_status: TrafficLightStatus):
        """绘制路口及其交通信号灯"""
        screen_pos = self.coordinate_transform(pos)
        
        # 绘制路口底色
        pygame.draw.circle(self.screen, Colors.GRAY, screen_pos, self.intersection_radius)
        
        # 绘制信号灯
        light_color = {
            TrafficLightStatus.RED: Colors.RED,
            TrafficLightStatus.GREEN: Colors.GREEN,
            TrafficLightStatus.YELLOW: Colors.YELLOW
        }[traffic_light_status]
        
        pygame.draw.circle(self.screen, light_color, 
                         (screen_pos[0], screen_pos[1] - 15), 5)
        
    def draw_vehicle(self, vehicle: Vehicle, direction: Direction):
        """绘制车辆"""
        # 使用实际屏幕坐标而不是网格坐标
        if vehicle.moving:
            screen_x = vehicle.screen_x * self.cell_size + self.width // 4
            screen_y = vehicle.screen_y * self.cell_size + self.height // 4
            screen_pos = (int(screen_x), int(screen_y))
        else:
            screen_pos = self.coordinate_transform(vehicle.current_position)
        
        # 用户车辆使用红色，其他车辆使用蓝色
        color = Colors.RED if vehicle.id == "user_car" else Colors.BLUE
        pygame.draw.circle(self.screen, color, screen_pos, self.vehicle_radius)
        
        # 绘制方向指示器
        direction_indicator = {
            Direction.STRAIGHT: (0, -10),
            Direction.LEFT: (-10, 0),
            Direction.RIGHT: (10, 0)
        }[direction]
        
        pygame.draw.line(self.screen, color,
                        screen_pos,
                        (screen_pos[0] + direction_indicator[0],
                         screen_pos[1] + direction_indicator[1]), 2)
        
    def show_arrival_notification(self):
        """显示到达目的地的提示"""
        self.show_arrival_message = True
        self.message_start_time = time.time()
    
    def render(self, traffic_system: 'TrafficSystem'):
        """渲染整个交通系统"""
        # 使用深色背景
        bg_color = (40, 44, 52)  # 深色背景
        grid_color = (50, 54, 62)  # 网格线颜色
        self.screen.fill(bg_color)
        
        # 绘制背景网格
        for x in range(0, self.width, 20):
            pygame.draw.line(self.screen, grid_color, (x, 0), (x, self.height))
        for y in range(0, self.height, 20):
            pygame.draw.line(self.screen, grid_color, (0, y), (self.width, y))
        
        # 绘制标题区域
        title_bg = pygame.Rect(0, 0, self.width, 50)
        pygame.draw.rect(self.screen, (30, 34, 42), title_bg)
        
        # 绘制标题
        title = self.small_font.render("路径规划系统 - 运行中", True, Colors.WHITE)
        self.screen.blit(title, (20, 15))
        
        # 绘制返回按钮
        # 检查鼠标是否悬停在按钮上
        mouse_pos = pygame.mouse.get_pos()
        back_button_rect = pygame.Rect(self.width - 140, 10, 120, 30)
        button_color = (61, 90, 254)  # 默认蓝色按钮
        hover_color = (94, 114, 235)  # 悬停时的颜色
        
        # 根据悬停状态选择颜色
        if back_button_rect.collidepoint(mouse_pos):
            button_color = hover_color
            # 添加悬停效果 - 左侧指示器
            indicator_rect = pygame.Rect(back_button_rect.x - 10, back_button_rect.y + back_button_rect.height // 2 - 8, 5, 16)
            pygame.draw.rect(self.screen, (255, 165, 0), indicator_rect, border_radius=2)
            
        # 绘制按钮
        pygame.draw.rect(self.screen, button_color, back_button_rect, border_radius=8)
        
        # 绘制按钮文字
        back_text = self.small_font.render("返回主菜单", True, Colors.WHITE)
        self.screen.blit(back_text, (back_button_rect.centerx - back_text.get_width() // 2, 
                                   back_button_rect.centery - back_text.get_height() // 2))
        
        # 保存按钮位置供事件处理使用
        self.back_button_rect = back_button_rect
        
        # 绘制信息面板背景
        panel_bg = pygame.Rect(self.width - 220, 60, 200, 150)
        pygame.draw.rect(self.screen, (30, 34, 42), panel_bg, border_radius=10)
        pygame.draw.rect(self.screen, (61, 90, 254), panel_bg, 2, border_radius=10)
        
        # 绘制基本信息
        info_texts = [
            f"车辆数量: {len(traffic_system.vehicles)}",
            f"交叉路口: {len(traffic_system.intersections)}",
            f"道路数量: {len(traffic_system.roads)}",
            f"车辆生成率: {traffic_system.vehicle_spawn_rate}",
        ]
        
        for i, text in enumerate(info_texts):
            info = self.small_font.render(text, True, Colors.WHITE)
            self.screen.blit(info, (self.width - 200, 70 + i * 30))
        
        # 绘制操作提示面板
        help_bg = pygame.Rect(10, self.height - 70, 300, 50)
        pygame.draw.rect(self.screen, (30, 34, 42), help_bg, border_radius=5)
        help_text = self.small_font.render("按ESC键返回主菜单", True, (200, 200, 200))
        self.screen.blit(help_text, (20, self.height - 55))
        
        # 创建一个城市模型背景效果
        # 绘制道路，使用更宽的道路宽度和更好的视觉效果
        for road in traffic_system.roads:
            start_pos = self.coordinate_transform(road.start)
            end_pos = self.coordinate_transform(road.end)
            
            # 根据密度计算颜色 - 使用从绿色到红色的渐变
            density = road.density
            # 创建一个渐变颜色：从绿色(低密度)到黄色(中密度)到红色(高密度)
            if density < 0.5:
                # 从绿色到黄色
                g = 255
                r = int(255 * (density * 2))
                road_color = (r, g, 0)
            else:
                # 从黄色到红色
                r = 255
                g = int(255 * (2 - density * 2))
                road_color = (r, g, 0)
            
            # 绘制道路底色 - 更宽的道路
            road_width = 12
            pygame.draw.line(self.screen, (60, 60, 60), start_pos, end_pos, road_width)
            
            # 绘制道路颜色指示器
            pygame.draw.line(self.screen, road_color, start_pos, end_pos, 6)
            
            # 绘制道路方向箭头 - 更明显的箭头
            self.draw_arrow(start_pos, end_pos, (220, 220, 220))
        
        # 绘制交叉路口，添加更多视觉细节
        for pos, intersection in traffic_system.intersections.items():
            screen_pos = self.coordinate_transform(pos)
            
            # 绘制交叉路口外圈
            pygame.draw.circle(self.screen, (80, 80, 80), screen_pos, self.intersection_radius + 4)
            
            # 绘制路口底色
            pygame.draw.circle(self.screen, (50, 50, 50), screen_pos, self.intersection_radius)
            
            # 绘制信号灯
            light_color = {
                TrafficLightStatus.RED: Colors.RED,
                TrafficLightStatus.GREEN: Colors.GREEN,
                TrafficLightStatus.YELLOW: Colors.YELLOW
            }[intersection.traffic_light.status]
            
            # 绘制信号灯背景
            pygame.draw.circle(self.screen, (30, 30, 30), 
                            (screen_pos[0], screen_pos[1] - 15), 7)
            
            # 绘制信号灯
            pygame.draw.circle(self.screen, light_color, 
                            (screen_pos[0], screen_pos[1] - 15), 5)
            
            # 添加坐标文本
            pos_text = self.small_font.render(f"{pos.x},{pos.y}", True, Colors.WHITE)
            text_pos = (screen_pos[0] - pos_text.get_width() // 2, 
                        screen_pos[1] + 15)
            self.screen.blit(pos_text, text_pos)
        
        # 绘制用户车辆，使用更详细的车辆模型
        for vehicle in traffic_system.vehicles:
            if vehicle.id == "user_car":  # 只渲染用户车辆
                direction = traffic_system.get_next_direction(vehicle)
                
                # 使用更详细的车辆绘制方法
                self.draw_detailed_vehicle(vehicle, direction)
                
                # 检查是否需要显示到达提示
                if self.show_arrival_message:
                    current_time = time.time()
                    if current_time - self.message_start_time < self.message_duration:
                        # 绘制半透明背景
                        s = pygame.Surface((self.width, 100))
                        s.set_alpha(180)
                        s.fill((0, 0, 0))
                        self.screen.blit(s, (0, self.height // 2 - 50))
                        
                        # 绘制提示文本
                        text = "已到达目的地！"
                        text_surface = self.font.render(text, True, Colors.WHITE)
                        text_rect = text_surface.get_rect(center=(self.width // 2, self.height // 2))
                        self.screen.blit(text_surface, text_rect)
                        
                        # 绘制装饰性元素
                        pygame.draw.line(self.screen, (255, 165, 0), 
                                      (self.width // 2 - 120, self.height // 2 + 20), 
                                      (self.width // 2 + 120, self.height // 2 + 20), 2)
                    else:
                        self.show_arrival_message = False
                
                # 绘制起点和终点标记
                if vehicle.route and len(vehicle.route) > 0:
                    # 起点标记（绿色）
                    start_pos = self.coordinate_transform(vehicle.route[0])
                    pygame.draw.circle(self.screen, Colors.GREEN, start_pos, 8, 2)
                    
                    # 终点标记（红色）
                    end_pos = self.coordinate_transform(vehicle.route[-1])
                    pygame.draw.circle(self.screen, Colors.RED, end_pos, 8, 2)
        
        pygame.display.flip()
    
    def draw_detailed_vehicle(self, vehicle: Vehicle, direction: Direction):
        """绘制更详细的车辆"""
        # 使用实际屏幕坐标而不是网格坐标
        if vehicle.moving:
            screen_x = vehicle.screen_x * self.cell_size + self.width // 4
            screen_y = vehicle.screen_y * self.cell_size + self.height // 4
            screen_pos = (int(screen_x), int(screen_y))
        else:
            screen_pos = self.coordinate_transform(vehicle.current_position)
        
        # 车辆尺寸
        car_width, car_height = 16, 10
        
        # 根据方向计算旋转角度
        angle = 0
        if direction == Direction.LEFT:
            angle = 180
        elif direction == Direction.RIGHT:
            angle = 0
        else:  # STRAIGHT
            # 根据路径计算角度
            if len(vehicle.route) > vehicle.current_route_index + 1:
                current = vehicle.route[vehicle.current_route_index]
                next_pos = vehicle.route[vehicle.current_route_index + 1]
                dx = next_pos.x - current.x
                dy = next_pos.y - current.y
                if dx > 0:
                    angle = 0  # 向右
                elif dx < 0:
                    angle = 180  # 向左
                elif dy > 0:
                    angle = 90  # 向下
                elif dy < 0:
                    angle = 270  # 向上
        
        # 旋转后的坐标计算
        cos_angle = math.cos(math.radians(angle))
        sin_angle = math.sin(math.radians(angle))
        
        # 车身顶点（默认方向为右）
        vertices = [
            (-car_width // 2, -car_height // 2),  # 左上
            (car_width // 2, -car_height // 2),   # 右上
            (car_width // 2, car_height // 2),    # 右下
            (-car_width // 2, car_height // 2)    # 左下
        ]
        
        # 应用旋转并平移到正确位置
        rotated_vertices = []
        for x, y in vertices:
            rotated_x = x * cos_angle - y * sin_angle + screen_pos[0]
            rotated_y = x * sin_angle + y * cos_angle + screen_pos[1]
            rotated_vertices.append((rotated_x, rotated_y))
        
        # 绘制车身
        color = Colors.RED if vehicle.id == "user_car" else Colors.BLUE
        pygame.draw.polygon(self.screen, color, rotated_vertices)
        
        # 绘制轮廓
        pygame.draw.polygon(self.screen, (0, 0, 0), rotated_vertices, 1)
        
        # 绘制车头指示
        head_pos = (
            car_width // 2 * 0.7 * cos_angle + screen_pos[0],
            car_width // 2 * 0.7 * sin_angle + screen_pos[1]
        )
        pygame.draw.circle(self.screen, (255, 255, 255), (int(head_pos[0]), int(head_pos[1])), 2)
        
    def handle_events(self) -> bool:
        """处理pygame事件，返回是否继续运行"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    return False
            if event.type == pygame.MOUSEBUTTONDOWN:
                # 检查是否点击了返回按钮
                if hasattr(self, 'back_button_rect') and self.back_button_rect.collidepoint(event.pos):
                    # 返回特殊值，表示要返回主菜单
                    return "back_to_main"
        return True
    
    def quit(self):
        """清理pygame资源"""
        pygame.quit()

    def draw_input_ui(self):
        """绘制输入界面"""
        # 背景色
        bg_color = (40, 44, 52)  # 深色背景
        grid_color = (60, 64, 72)  # 网格线颜色
        highlight_color = (61, 90, 254)  # 高亮色
        
        # 填充背景
        self.screen.fill(bg_color)
        
        # 绘制网格背景
        for x in range(0, self.width, 20):
            pygame.draw.line(self.screen, grid_color, (x, 0), (x, self.height))
        for y in range(0, self.height, 20):
            pygame.draw.line(self.screen, grid_color, (0, y), (self.width, y))
        
        # 绘制标题区域
        title_bg = pygame.Rect(0, 0, self.width, 80)
        pygame.draw.rect(self.screen, (30, 34, 42), title_bg)
        
        # 绘制标题
        state_text = "选择起点" if self.input_state == "start" else "选择终点"
        title = self.font.render(f"请{state_text}", True, Colors.WHITE)
        self.screen.blit(title, (self.width // 2 - title.get_width() // 2, 25))
        
        # 绘制装饰线
        pygame.draw.line(self.screen, (255, 165, 0), 
                        (self.width // 2 - 100, 65), 
                        (self.width // 2 + 100, 65), 3)
        
        # 绘制说明面板
        panel_bg = pygame.Rect(20, self.height - 130, self.width - 40, 100)
        pygame.draw.rect(self.screen, (30, 34, 42), panel_bg, border_radius=10)
        pygame.draw.rect(self.screen, (50, 54, 62), panel_bg, 2, border_radius=10)
        
        # 绘制操作说明
        instructions = [
            "• 使用鼠标左键点击网格上的交叉点选择起点和终点",
            "• 绿色点表示起点，红色点表示终点",
            "• 按ESC键退出系统或点击左上角\"返回\"按钮返回主菜单"
        ]
        for i, text in enumerate(instructions):
            instruction = self.small_font.render(text, True, (200, 200, 200))
            self.screen.blit(instruction, (40, self.height - 110 + i * 30))
        
        # 绘制城市模型背景
        city_bg_height = 80
        road_width = 30
        
        # 水平道路
        for i in range(5):
            y = self.height // 4 + i * self.cell_size
            pygame.draw.rect(self.screen, (60, 60, 60), (self.width // 4 - 50, y - road_width//2, self.width // 2 + 100, road_width))
            
            # 道路中线
            for j in range(10):
                x = self.width // 4 - 50 + j * 60
                if j % 2 == 0:  # 只绘制部分中线，形成虚线效果
                    pygame.draw.rect(self.screen, (255, 255, 255), (x, y - 1, 30, 2))
        
        # 垂直道路
        for i in range(5):
            x = self.width // 4 + i * self.cell_size
            pygame.draw.rect(self.screen, (60, 60, 60), (x - road_width//2, self.height // 4 - 50, road_width, self.height // 2 + 100))
            
            # 道路中线
            for j in range(8):
                y = self.height // 4 - 50 + j * 60
                if j % 2 == 0:  # 只绘制部分中线，形成虚线效果
                    pygame.draw.rect(self.screen, (255, 255, 255), (x - 1, y, 2, 30))
        
        # 绘制每个交叉点
        for i in range(5):
            for j in range(5):
                pos = Position(i, j)
                screen_pos = self.coordinate_transform(pos)
                
                # 绘制交叉路口背景（深色圆形）
                pygame.draw.circle(self.screen, (50, 50, 50), screen_pos, self.intersection_radius + 5)
                
                # 根据状态决定颜色
                if pos == self.start_pos:
                    color = Colors.GREEN
                    size = self.intersection_radius + 5
                elif pos == self.dest_pos:
                    color = Colors.RED
                    size = self.intersection_radius + 5
                elif pos == self.selected_pos:
                    color = Colors.YELLOW
                    size = self.intersection_radius + 2
                else:
                    color = Colors.GRAY
                    size = self.intersection_radius
                
                # 绘制交叉点
                pygame.draw.circle(self.screen, color, screen_pos, size)
                
                # 添加坐标文本
                pos_text = self.small_font.render(f"{i},{j}", True, Colors.WHITE)
                text_pos = (screen_pos[0] - pos_text.get_width() // 2, 
                           screen_pos[1] - pos_text.get_height() // 2)
                self.screen.blit(pos_text, text_pos)
        
        # 绘制选择状态提示
        if self.start_pos:
            start_info = self.small_font.render(f"起点: ({self.start_pos.x}, {self.start_pos.y})", True, Colors.GREEN)
            self.screen.blit(start_info, (20, 100))
        
        if self.dest_pos:
            dest_info = self.small_font.render(f"终点: ({self.dest_pos.x}, {self.dest_pos.y})", True, Colors.RED)
            self.screen.blit(dest_info, (self.width - 20 - dest_info.get_width(), 100))

    def get_input_positions(self) -> tuple[Position, Position]:
        """获取用户输入的起始点和目标点"""
        # 重置选择状态
        self.input_state = "start"
        self.selected_pos = None
        self.start_pos = None
        self.dest_pos = None
        
        # 创建确认和返回按钮
        confirm_button = None
        back_button = pygame.Rect(20, 20, 100, 40)
        
        while True:
            self.screen.fill((40, 44, 52))  # 使用深色背景
            self.draw_input_ui()
            
            # 如果已选择起点和终点，显示确认按钮
            if self.dest_pos:
                confirm_button = pygame.Rect(self.width - 150, self.height - 180, 120, 40)
                # 绘制确认按钮
                pygame.draw.rect(self.screen, (0, 180, 0), confirm_button, border_radius=5)
                confirm_text = self.small_font.render("确认选择", True, Colors.WHITE)
                self.screen.blit(confirm_text, (confirm_button.centerx - confirm_text.get_width() // 2, 
                                             confirm_button.centery - confirm_text.get_height() // 2))
            
            # 绘制返回按钮
            pygame.draw.rect(self.screen, (180, 0, 0), back_button, border_radius=5)
            back_text = self.small_font.render("返回", True, Colors.WHITE)
            self.screen.blit(back_text, (back_button.centerx - back_text.get_width() // 2, 
                                      back_button.centery - back_text.get_height() // 2))
            
            pygame.display.flip()
            
            # 处理事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    return None, None
                
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        return None, None
                
                if event.type == pygame.MOUSEBUTTONDOWN:
                    mouse_pos = pygame.mouse.get_pos()
                    
                    # 检查按钮点击 - 所有鼠标按钮都可以点击UI按钮
                    if back_button.collidepoint(mouse_pos):
                        # 返回特殊值，表示要返回主菜单
                        return "back_to_main"
                    
                    if confirm_button and confirm_button.collidepoint(mouse_pos):
                        if self.start_pos and self.dest_pos:
                            return self.start_pos, self.dest_pos
                    
                    # 只有鼠标左键点击才能选择网格坐标
                    # pygame中，按钮1是左键，4是滚轮上滚，5是滚轮下滚
                    if event.button == 1:  # 仅限鼠标左键
                        # 获取鼠标位置并转换为网格坐标
                        grid_x = int((mouse_pos[0] - self.width // 4) / self.cell_size + 0.5)
                        grid_y = int((mouse_pos[1] - self.height // 4) / self.cell_size + 0.5)
                        
                        # 检查坐标是否有效
                        if 0 <= grid_x <= 4 and 0 <= grid_y <= 4:
                            pos = Position(grid_x, grid_y)
                            self.selected_pos = pos
                            
                            if self.input_state == "start":
                                if pos != self.dest_pos:  # 确保起点和终点不同
                                    self.start_pos = pos
                                    self.input_state = "dest"
                            elif self.input_state == "dest" and pos != self.start_pos:
                                self.dest_pos = pos
            
            time.sleep(0.05)

    def show_main_menu(self) -> str:
        """显示主菜单，返回用户选择的选项"""
        # 创建按钮
        start_button = pygame.Rect(self.width // 2 - 150, self.height // 2 - 30, 300, 60)
        params_button = pygame.Rect(self.width // 2 - 150, self.height // 2 + 50, 300, 60)
        quit_button = pygame.Rect(self.width // 2 - 150, self.height // 2 + 130, 300, 60)
        
        # 添加注销按钮
        logout_button = pygame.Rect(self.width // 2 + 170, 50, 120, 40)
        
        # 定义颜色
        bg_color1 = (40, 44, 52)  # 深色背景
        bg_color2 = (30, 34, 42)  # 更深的背景色
        button_color = (61, 90, 254)  # 蓝色按钮
        button_hover_color = (94, 114, 235)  # 悬停时的按钮颜色
        accent_color = (255, 165, 0)  # 强调色（橙色）
        
        # 加载背景网格
        def draw_grid(surface, grid_size=20, line_color=(50, 54, 62)):
            for x in range(0, self.width, grid_size):
                pygame.draw.line(surface, line_color, (x, 0), (x, self.height))
            for y in range(0, self.height, grid_size):
                pygame.draw.line(surface, line_color, (0, y), (self.width, y))
        
        # 动画效果的参数
        animation_speed = 0.5
        animation_time = 0
        car_positions = [(0, self.height // 2), (self.width, self.height // 3)]
        
        running = True
        clock = pygame.time.Clock()
        while running:
            dt = clock.tick(60) / 1000.0  # 获取帧间时间差（秒）
            animation_time += dt
            
            mouse_pos = pygame.mouse.get_pos()
            
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return "quit"
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if start_button.collidepoint(mouse_pos):
                        return "start"
                    elif params_button.collidepoint(mouse_pos):
                        return "params"
                    elif quit_button.collidepoint(mouse_pos):
                        return "quit"
                    # 处理注销按钮点击
                    elif logout_button.collidepoint(mouse_pos) and self.user_system.is_logged_in():
                        self.user_system.logout()
                        # 注销后返回到登录界面
                        return "logout"
            
            # 绘制背景
            self.screen.fill(bg_color1)
            
            # 绘制网格背景
            draw_grid(self.screen)
            
            # 绘制装饰性道路
            road_y = self.height // 2 + 250
            pygame.draw.rect(self.screen, (60, 60, 60), (0, road_y - 40, self.width, 80))
            # 绘制道路中线
            for i in range(10):
                x = (i * 100 + animation_time * 200) % (self.width + 200) - 100
                pygame.draw.rect(self.screen, (255, 255, 255), (x, road_y - 2, 50, 4))
            
            # 绘制移动的小车
            car_width, car_height = 60, 30
            for i, (start_x, car_y) in enumerate(car_positions):
                # 计算当前位置
                direction = 1 if i == 0 else -1
                car_x = (start_x + direction * animation_time * 150 * animation_speed) % (self.width + car_width * 2)
                car_x = car_x - car_width if direction > 0 else self.width - car_x
                
                # 绘制车身
                color = Colors.RED if i == 0 else Colors.BLUE
                pygame.draw.rect(self.screen, color, (car_x, car_y, car_width, car_height), border_radius=8)
                # 绘制车窗
                pygame.draw.rect(self.screen, (200, 200, 200), (car_x + 40, car_y + 5, 15, 8), border_radius=2)
                # 绘制车轮
                pygame.draw.circle(self.screen, (40, 40, 40), (car_x + 15, car_y + car_height), 8)
                pygame.draw.circle(self.screen, (40, 40, 40), (car_x + car_width - 15, car_y + car_height), 8)
            
            # 绘制标题区域背景
            title_bg = pygame.Rect(0, 30, self.width, 120)
            pygame.draw.rect(self.screen, bg_color2, title_bg)
            
            # 绘制标题
            title = self.font.render("路径规划系统", True, Colors.WHITE)
            subtitle = self.small_font.render("Path Planning System", True, (180, 180, 180))
            self.screen.blit(title, (self.width // 2 - title.get_width() // 2, 50))
            self.screen.blit(subtitle, (self.width // 2 - subtitle.get_width() // 2, 100))
            
            # 绘制装饰性图案
            pygame.draw.line(self.screen, accent_color, 
                            (self.width // 2 - 100, 130), 
                            (self.width // 2 + 100, 130), 3)
            
            # 绘制当前登录用户信息
            if self.user_system.is_logged_in():
                user_text = self.small_font.render(f"当前用户: {self.user_system.get_current_user()}", True, Colors.WHITE)
                self.screen.blit(user_text, (20, 50))
            
            # 绘制按钮
            for button, text, y_offset in [
                (start_button, "开始模拟", 0),
                (params_button, "参数设置", 1),
                (quit_button, "退出系统", 2)
            ]:
                # 是否悬停
                is_hover = button.collidepoint(mouse_pos)
                
                # 按钮背景
                color = button_hover_color if is_hover else button_color
                pygame.draw.rect(self.screen, color, button, border_radius=10)
                
                # 按钮文字
                btn_text = self.font.render(text, True, Colors.WHITE)
                text_x = button.centerx - btn_text.get_width() // 2
                text_y = button.centery - btn_text.get_height() // 2
                self.screen.blit(btn_text, (text_x, text_y))
                
                # 悬停时的指示器
                if is_hover:
                    indicator_rect = pygame.Rect(button.x - 15, button.y + button.height // 2 - 8, 8, 16)
                    pygame.draw.rect(self.screen, accent_color, indicator_rect, border_radius=4)
            
            # 绘制版本信息
            version_text = self.small_font.render("版本 1.0.0", True, (120, 120, 120))
            self.screen.blit(version_text, (self.width - version_text.get_width() - 20, self.height - 40))
            
            # 绘制说明
            instruction = self.small_font.render("使用鼠标点击选项进行操作", True, (200, 200, 200))
            self.screen.blit(instruction, (self.width // 2 - instruction.get_width() // 2, self.height - 80))
            
            # 绘制注销按钮（仅当用户已登录时）
            if self.user_system.is_logged_in():
                logout_color = button_hover_color if logout_button.collidepoint(mouse_pos) else button_color
                pygame.draw.rect(self.screen, logout_color, logout_button, border_radius=6)
                
                logout_text = self.small_font.render("退出登录", True, Colors.WHITE)
                self.screen.blit(logout_text, (logout_button.centerx - logout_text.get_width() // 2, 
                                             logout_button.centery - logout_text.get_height() // 2))
            
            pygame.display.flip()
            clock.tick(60)  # 限制帧率
        
        return "quit"  # 默认返回退出 

    def _is_valid_email(self, email: str) -> bool:
        """检查邮箱格式是否有效"""
        pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
        return re.match(pattern, email) is not None
    
    def show_login_register_screen(self) -> str:
        """显示登录和注册界面"""
        # 定义颜色
        bg_color = (40, 44, 52)  # 深色背景
        panel_color = (30, 34, 42)  # 面板背景色
        button_color = (61, 90, 254)  # 蓝色按钮
        button_hover_color = (94, 114, 235)  # 悬停时的按钮颜色
        input_bg_color = (50, 54, 62)  # 输入框背景色
        input_active_color = (70, 74, 82)  # 输入框激活背景色
        border_color = (100, 100, 100)  # 边框颜色
        error_color = (255, 100, 100)  # 错误消息颜色
        success_color = (100, 255, 100)  # 成功消息颜色
        
        # 创建面板和按钮
        panel_width, panel_height = 500, 360
        panel_rect = pygame.Rect(
            self.width // 2 - panel_width // 2,
            self.height // 2 - panel_height // 2,
            panel_width, panel_height
        )
        
        # 输入框
        input_height = 40
        username_rect = pygame.Rect(panel_rect.x + 50, panel_rect.y + 80, panel_width - 100, input_height)
        password_rect = pygame.Rect(panel_rect.x + 50, panel_rect.y + 160, panel_width - 100, input_height)
        
        # 登录、注册和返回按钮
        button_width, button_height = 120, 40
        login_button = pygame.Rect(panel_rect.x + 50, panel_rect.y + 240, button_width, button_height)
        register_button = pygame.Rect(panel_rect.x + panel_width - 50 - button_width, panel_rect.y + 240, button_width, button_height)
        back_button = pygame.Rect(panel_rect.x + panel_width // 2 - button_width // 2, panel_rect.y + 300, button_width, button_height)
        
        # 状态变量
        active_input = None
        username = ""
        password = ""
        message = ""
        message_color = error_color
        
        # 切换登录和注册模式
        is_login_mode = True
        
        # 绘制背景网格
        def draw_grid():
            for x in range(0, self.width, 20):
                pygame.draw.line(self.screen, (50, 54, 62), (x, 0), (x, self.height))
            for y in range(0, self.height, 20):
                pygame.draw.line(self.screen, (50, 54, 62), (0, y), (self.width, y))
        
        running = True
        clock = pygame.time.Clock()
        
        # 光标闪烁
        cursor_visible = True
        last_cursor_toggle = time.time()
        
        # 启用文本输入（确保已激活）
        pygame.key.set_repeat(500, 30)
        input_enabled = True
        
        # 允许的字符
        valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."
        
        while running:
            # 处理光标闪烁
            current_time = time.time()
            if current_time - last_cursor_toggle > 0.5:
                cursor_visible = not cursor_visible
                last_cursor_toggle = current_time
            
            # 处理事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return "quit"
                
                # 鼠标点击处理
                if event.type == pygame.MOUSEBUTTONDOWN:
                    # 检查点击的是哪个输入框
                    if username_rect.collidepoint(event.pos):
                        active_input = "username"
                    elif password_rect.collidepoint(event.pos):
                        active_input = "password"
                    else:
                        active_input = None
                    
                    # 处理按钮点击
                    if login_button.collidepoint(event.pos):
                        if is_login_mode:
                            # 验证登录
                            if not username or not password:
                                message = "用户名和密码不能为空"
                                message_color = error_color
                            else:
                                success, msg = self.user_system.login(username, password)
                                message = msg
                                message_color = success_color if success else error_color
                                if success:
                                    time.sleep(1)  # 显示成功消息
                                    return "login_success"
                        else:
                            # 切换到登录模式
                            is_login_mode = True
                            message = "切换到登录模式"
                            message_color = success_color
                    
                    elif register_button.collidepoint(event.pos):
                        if not is_login_mode:
                            # 注册用户
                            if not username or not password:
                                message = "用户名和密码不能为空"
                                message_color = error_color
                            else:
                                success, msg = self.user_system.register(username, password)
                                message = msg
                                message_color = success_color if success else error_color
                                if success:
                                    is_login_mode = True
                                    message = "注册成功，请登录"
                                    message_color = success_color
                        else:
                            # 切换到注册模式
                            is_login_mode = False
                            message = "切换到注册模式"
                            message_color = success_color
                    
                    elif back_button.collidepoint(event.pos):
                        return "back"
                
                # 键盘输入处理（针对特殊按键）
                if event.type == pygame.KEYDOWN and active_input:
                    # 处理特殊按键
                    if event.key == pygame.K_BACKSPACE:
                        # 退格键，删除最后一个字符
                        if active_input == "username":
                            username = username[:-1]
                        elif active_input == "password":
                            password = password[:-1]
                    
                    elif event.key == pygame.K_TAB:
                        # Tab键切换输入框
                        active_input = "password" if active_input == "username" else "username"
                    
                    elif event.key == pygame.K_RETURN:
                        # 回车键执行登录/注册操作
                        if is_login_mode:
                            if username and password:
                                success, msg = self.user_system.login(username, password)
                                message = msg
                                message_color = success_color if success else error_color
                                if success:
                                    time.sleep(1)
                                    return "login_success"
                            else:
                                message = "用户名和密码不能为空"
                                message_color = error_color
                        else:
                            if username and password:
                                success, msg = self.user_system.register(username, password)
                                message = msg
                                message_color = success_color if success else error_color
                                if success:
                                    is_login_mode = True
                                    message = "注册成功，请登录"
                                    message_color = success_color
                            else:
                                message = "用户名和密码不能为空"
                                message_color = error_color
                
                # 处理文本输入事件（仅用这一种方式处理文本输入）
                if event.type == pygame.TEXTINPUT and active_input:
                    for char in event.text:
                        if char in valid_chars:
                            if active_input == "username" and len(username) < 20:
                                username += char
                            elif active_input == "password" and len(password) < 20:
                                password += char
            
            # 清屏并绘制背景
            self.screen.fill(bg_color)
            draw_grid()
            
            # 绘制面板
            pygame.draw.rect(self.screen, panel_color, panel_rect, border_radius=10)
            pygame.draw.rect(self.screen, border_color, panel_rect, 2, border_radius=10)
            
            # 绘制标题
            title_text = "用户登录" if is_login_mode else "用户注册"
            title = self.font.render(title_text, True, Colors.WHITE)
            self.screen.blit(title, (panel_rect.centerx - title.get_width() // 2, panel_rect.y + 20))
            
            # 绘制用户名输入框
            username_label = self.small_font.render("用户名:", True, Colors.WHITE)
            self.screen.blit(username_label, (username_rect.x, username_rect.y - 30))
            
            username_input_color = input_active_color if active_input == "username" else input_bg_color
            pygame.draw.rect(self.screen, username_input_color, username_rect, border_radius=6)
            pygame.draw.rect(self.screen, border_color, username_rect, 1, border_radius=6)
            
            username_surface = self.small_font.render(username, True, Colors.WHITE)
            self.screen.blit(username_surface, (username_rect.x + 10, username_rect.y + (input_height - username_surface.get_height()) // 2))
            
            # 添加输入光标
            if active_input == "username" and cursor_visible:
                cursor_x = username_rect.x + 10 + username_surface.get_width()
                pygame.draw.line(self.screen, Colors.WHITE, 
                                (cursor_x, username_rect.y + 10),
                                (cursor_x, username_rect.y + input_height - 10), 2)
            
            # 绘制密码输入框
            password_label = self.small_font.render("密码:", True, Colors.WHITE)
            self.screen.blit(password_label, (password_rect.x, password_rect.y - 30))
            
            password_input_color = input_active_color if active_input == "password" else input_bg_color
            pygame.draw.rect(self.screen, password_input_color, password_rect, border_radius=6)
            pygame.draw.rect(self.screen, border_color, password_rect, 1, border_radius=6)
            
            # 显示密码为星号
            masked_password = "*" * len(password)
            password_surface = self.small_font.render(masked_password, True, Colors.WHITE)
            self.screen.blit(password_surface, (password_rect.x + 10, password_rect.y + (input_height - password_surface.get_height()) // 2))
            
            # 添加输入光标
            if active_input == "password" and cursor_visible:
                cursor_x = password_rect.x + 10 + password_surface.get_width()
                pygame.draw.line(self.screen, Colors.WHITE, 
                                (cursor_x, password_rect.y + 10),
                                (cursor_x, password_rect.y + input_height - 10), 2)
            
            # 绘制按钮
            for button, text in [
                (login_button, "登录" if is_login_mode else "切换到登录"),
                (register_button, "注册" if not is_login_mode else "切换到注册"),
                (back_button, "返回")
            ]:
                is_hover = button.collidepoint(pygame.mouse.get_pos())
                button_bg_color = button_hover_color if is_hover else button_color
                
                pygame.draw.rect(self.screen, button_bg_color, button, border_radius=6)
                
                btn_text = self.small_font.render(text, True, Colors.WHITE)
                self.screen.blit(btn_text, (button.centerx - btn_text.get_width() // 2, 
                                           button.centery - btn_text.get_height() // 2))
            
            # 显示消息
            if message:
                message_surface = self.small_font.render(message, True, message_color)
                self.screen.blit(message_surface, (panel_rect.centerx - message_surface.get_width() // 2, 
                                                  panel_rect.y + 210))
            
            pygame.display.flip()
            clock.tick(60)
            
        return "back" 